
package com.lmx.persistence.service;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.ICommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.HttpRequestUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.common.util.SMSUtil;
import com.lmx.repoDomain.tmodel.Bed;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.Device;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.HbeaconWarning;
import com.lmx.repoDomain.tmodel.Message;
import com.lmx.repoDomain.tmodel.business.User;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

/**
 * 
 * 
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class HbeaconService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	private Properties properties = PropertiesFileUtil.getApplicationProperties();

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected UserService userService;

	@Autowired
	protected CustomerService customerService;

	@Autowired
	protected WorkPlaceService workPlaceService;

	@Autowired
	protected CommonService commonService;
	
	@Autowired
	protected DeviceService deviceService;
	
	@Autowired
	protected EmployeeService employeeService;
	
	@Autowired
	protected NursingService nursingService;

	// 将数据对应关系数据写进文件
	public String getScannerHbeaconData() {
		String hbeaconData = HttpRequestUtil.sendGet("http://test.tnb99.cn/HbeaconScannerData");
		// 写到本地文件
		bufferedWriter(hbeaconData, "C:\\hbeacon\\hbeacon.properties", "C:\\hbeacon");
		return hbeaconData;

		// {"data":[{"scanner":"fx000000000","hbeacons":["cb0000004","cb0000005","cb0000006"]},{"scanner":"fx000000001","hbeacons":["cb0000001","cb0000002","cb0000003"]}],"version":1488159336}
	}

	public void bufferedWriter(String str, String filePath, String rootPath) {
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			File path = new File(rootPath);
			if (!path.exists()) {
				path.mkdirs();
			}
			File file = new File(filePath);
			if (!file.exists()) {
				file.createNewFile();
			}
			fw = new FileWriter(file);
			bw = new BufferedWriter(fw);
			bw.write(str);
		} catch (IOException e) {
			logger.debug("bufferedWriter error "+e);
		} finally {
			try {
				// bw.flush();
				bw.close();
				fw.close();
			} catch (IOException e) {
				logger.debug(" bufferedWriter error "+e);
			}
		}
	}

	// 形成按键手环对应关系的json数据
	public String getHbeaconRelationData(Long tenantId) {
		List<String> buttonList = new ArrayList<String>();// 按键数据
		List<String> braceletList = new ArrayList<String>();// 手环数据
		Map<String, String> messageMap = new HashMap<String, String>();// 按键显示数据
		Map<String, Object> dataMap = new HashMap<String, Object>();// 最终数据
		Map<String, List> dataMapTemp = new HashMap<String, List>();// 暂存
		List<Map> relationObjects = new ArrayList<Map>();// relation数据
		dataMap.put("version", (int) (System.currentTimeMillis() / 1000));// 版本号
		//由BedNurseGroup与EmployeeNursingGroup获取床位对应的护理人员
		StringBuilder sql =new StringBuilder( " select a.bed, a.group, e.employee from BedNurseGroup a , EmployeeNursingGroup e  "
				+ " where  a.delStatus != ?1   and e.delStatus != ?1  " 
				+ " and a.bed.button is not null  and a.bed is not null  " 
				+ " and a.group.id=e.group.id  ");
		if (tenantId > 0) {
			sql.append( " and a.tenant.id=" + tenantId);
		}
		List dataList = this.em.createQuery(sql.toString()).setParameter(1, (short) 1).getResultList();
		Iterator it = dataList.iterator();
		while (it.hasNext()) {
			Object[] res = (Object[]) it.next();
			Bed bed = (Bed) res[0];
			// NurseGroup group = (NurseGroup) res[1];
			Employee employee = (Employee) res[2];
			if (bed.getButton() != null) {
				Device button = bed.getButton();
				// 添加与床位绑定手环 
				if (!buttonList.contains(button.getSeq())) {
					buttonList.add(button.getSeq());
					dataMapTemp.put(button.getSeq(), new ArrayList<String>());
				}
				// 按键显示信息
				if (!messageMap.containsKey(button.getSeq())) {
					//messageMap.put(button.getSeq(), bed.getId().toString());
					messageMap.put(button.getSeq(), bed.getName());
				}
			}
			// 手环列表 以及 按键与手环对应关系
			if (employee.getBracelet() != null) {
				// 添加员工手环
				if (!braceletList.contains(employee.getBracelet().getSeq())) {
					braceletList.add(employee.getBracelet().getSeq()); //
				}
				// 按键与手环对应关系
				if (bed.getButton() != null) {
					Device button = bed.getButton();
					if (!dataMapTemp.get(button.getSeq()).contains(employee.getBracelet().getSeq())) {
						dataMapTemp.get(button.getSeq()).add(employee.getBracelet().getSeq());//
					}
				}
			}
		} // while end
		for (String button : buttonList) {
			Map<String, Object> mapTemp = new HashMap<String, Object>();
			mapTemp.put("bands", dataMapTemp.get(button));// 按键对应手环
			mapTemp.put("button", button);
			mapTemp.put("timeout", 30);
			mapTemp.put("message", messageMap.get(button));// 手环显示数据
			relationObjects.add(mapTemp);
		}
		// String sql2 = " select a from Device a "
		// + " where a.delStatus != ?1 "
		// + " and ( a.deviceType.typecode =?2 or a.deviceType.typecode =?3 )" ;
		// // deviceType3 button deviceType4 shouhuan
		StringBuilder query = new StringBuilder(
				"select c.device from CustomerDevice c " + " where c.delStatus != ?1  " + " and c.customer is not null "
						+ " and c.device is not null " + " and c.device.deviceType.typecode=?2 ");
		List<Device> deviceCustomerList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2,CommonConstants.DICTTYPE.HBEACON_BRACELET.label()).getResultList();// 获取老人绑定手环
		if (deviceCustomerList != null && deviceCustomerList.size() > 0) {
			for (Device device : deviceCustomerList) {
				braceletList.add(device.getSeq());
			}
		}
		dataMap.put("relations", relationObjects);
		dataMap.put("buttons", buttonList);
		dataMap.put("bracelets", braceletList);
		JSONObject jsonMap = JSONObject.fromObject(dataMap);
		return jsonMap.toString();
	}

	/**
	 * 生成按键呼叫消息
	 */
	@Transactional
	public void buildHbeaconCallingMessage(String jsonData) {
		logger.debug("create hbeacon calling 1 "+jsonData);
		JSONObject data = JSONObject.fromObject(jsonData);
		JSONArray deviceData = data.getJSONArray("callingData");
		List<Long> deviceIds=new ArrayList<>();
		for (int i = 0; i < deviceData.size(); i++) {
			String deviceId = deviceData.getJSONObject(i).getString("deviceId");
			String scannerId = "";
			if (deviceData.getJSONObject(i).containsKey("scannerId")) {
				scannerId = deviceData.getJSONObject(i).getString("scannerId");
			}
			Device device=deviceService.getDeviceWithDeviceNo(deviceId);
			if(device!=null){
				deviceIds.add(device.getId());
			}
			Device scanner=deviceService.getDeviceWithDeviceNo(scannerId);
			if(scanner!=null){
				deviceIds.add(scanner.getId());
			}
			Integer callingTime = -1;
			String eventType="-1";
			if (deviceData.getJSONObject(i).containsKey("callingTime")) {
				callingTime = deviceData.getJSONObject(i).getInt("callingTime");
				if (deviceData.getJSONObject(i).containsKey("eventType")) {
					eventType = deviceData.getJSONObject(i).getString("eventType");
				}
			}
			Integer cancelTime = -1;
			if (deviceData.getJSONObject(i).containsKey("cancelTime")) {
				cancelTime = deviceData.getJSONObject(i).getInt("cancelTime");
			}
			Bed bed = workPlaceService.getBedWithDeviceNo(deviceId.toString());
			if (bed != null) {
				Customer customer = customerService.getCustomerWithBed(bed.getId());
				if (callingTime != -1) { // 按键呼叫信息
					//按键未复位此次消息不进行处理
					if (ActionContextHolder.getCallingList() != null
							&& ActionContextHolder.getCallingList().contains(deviceId)) {
						return;
					}
					//将按键加入未复位列表
					if (ActionContextHolder.getCallingList() != null) {
						ActionContextHolder.getCallingList().add(deviceId);
					}else{
						ActionContextHolder.setCallingList(new ArrayList<String>());
						ActionContextHolder.getCallingList().add(deviceId);
					}
					List<User> users = userService.getAllUserList(bed.getTenant());// 本机构所有人
					if (users != null && users.size() > 0) {
						// 建立预警信息 此床位已存在则不创建
						StringBuilder sqlHb =new StringBuilder("select c from HbeaconWarning c where c.delStatus != ?1 and c.bed.id=?2 and c.flag.typecode=?3");
						List dataList = this.em
								.createQuery(sqlHb.toString())
								.setParameter(1, (short) 1).setParameter(2, bed.getId())
								.setParameter(3, CommonConstants.DICTTYPE.BUTTON_STATUS_1.label()).getResultList();
						if (dataList == null || dataList.size() == 0) { // 尚无此床位未处理的的预警信息
							// 建立预警信息
							HbeaconWarning warning = new HbeaconWarning();
							warning.setScannerId(deviceId);
							warning.setCallTime(callingTime);
							warning.setBed(bed);
							warning.setCreateDateTime(CommonUtil.getCurrTimes());
							warning.setTenant(bed.getTenant());
							warning.setDelStatus((short) 0);
							warning.setFlag(commonService.getDicttype(CommonConstants.DICTTYPE.BUTTON_STATUS_1.label()));
							if (CommonConstants.BUTTON_CALLING_TYPE.OLD_CALLING.label().equals(eventType)) {
								warning.setReason(CommonConstants.BUTTON_CALLING_TYPE.OLD_CALLING_NOTE.label());
							}  
							if (CommonConstants.BUTTON_CALLING_TYPE.OLD_YIWAI.label().equals(eventType)) {
								warning.setReason(CommonConstants.BUTTON_CALLING_TYPE.OLD_YIWAI_NOTE.label());
							} 
							if (CommonConstants.BUTTON_CALLING_TYPE.NORMAL.label().equals(eventType)) {
								warning.setReason(CommonConstants.BUTTON_CALLING_TYPE.NORMAL_NOTE.label());
							}
		
							if (customer != null) {
								warning.setCaller(customer);
							}
							warning.setCreateDateTime(CommonUtil.getCurrTimes());
							dslJpaService.setEntityClass(HbeaconWarning.class);
							dslJpaService.create(warning);
							// 建立 Message提醒
							Short detailType = (short) ICommonConstants.REMINDDETAILTYPE.HBEACONCALL.ordinal(); // 提醒详细类型
							Message message = new Message();
							message.setType(
									new Integer(CommonConstants.MESSAGE.MESSAGETYPE_NOTICE.label()).shortValue());
							message.setCode(CommonConstants.MESSAGE.MESSAGECODE_CALLINGNOTICE.label());
							message.setCreateTime(CommonUtil.getCurrTimes());
							message.setType((short) ICommonConstants.MESSAGETYPE.REMIND.ordinal());
							message.setDetailType(detailType);
							message.setTenant(bed.getTenant());
							// 设置content debugTest
							Map<String, String> msgMap = new HashMap<String, String>();
							// message.setToUser(user);
							// 设置消息内容
							msgMap.put("createTime", callingTime.toString());
							if (customer != null) {
								msgMap.put("customerId", customer.getId().toString());
								msgMap.put("customerName", customer.getName());
							}
							msgMap.put("bedId", bed.getId().toString());
							// msgMap.put("bedName", bed.getName());
							msgMap.put("content", CommonConstants.BUTTON_CALLING_TYPE.NORMAL_NOTE.label());
							message.setContent(CommonUtil.mapToJsonString(msgMap));
							// 使用类型作为通知的业务类型
							message.setBusiness("buttonCalling");
							message.setHasRead(new Integer(0).shortValue());
							// 取得需要发送的用户--发送给所有本机构的人员
							message.setUserList(users);
							// if (dataList == null || dataList.size() == 0) {
							// // 尚无此床位未处理的的预警信息
							dslJpaService.setEntityClass(Message.class);
							message = (Message) dslJpaService.create(message);
							// }
							ActionContextHolder.getMessageQueue().addWarningMsg(message);
							//短息通知
							List<Employee> staffsOnTime = employeeService.findByWorkTimeSetting(bed.getTenant().getId(),(long) CommonUtil.getCurrTimes());// 当前值班Staff
							List<Employee> staffs=nursingService.getEmployeeByCID(customer.getId());//护理组成员
							SMSUtil smsUtil = new SMSUtil();
							for (Employee staff : staffsOnTime) {
								if(staffs.contains(staff)){
									if (staff != null && staff.getStaffTel() != null && !"".equals(staff.getStaffTel())) {
										smsUtil.sendSMS(staff.getStaffTel(),
												"房间" + customer.getBed().getRoom().getName() + "-" + customer.getName(),
												"calling");
									}
								}
							}// end for staff
						}// end if datalist
					}

				} // callingTime
				if (cancelTime != -1) {// 按键呼叫取消信息
					//将该设备id从未复位按键列表中清除
					if (!"".equals(deviceId) && deviceId != null
							&& ActionContextHolder.getCallingList().contains(deviceId)) {
						ActionContextHolder.getCallingList().remove(deviceId);
					}
					StringBuilder sqlHb =new StringBuilder("select c from HbeaconWarning c where c.delStatus != ?1 and c.scannerId=?2 and c.flag.typecode=?3");
					List dataList = this.em
							.createQuery(sqlHb.toString())
							.setParameter(1, (short) 1).setParameter(2, deviceId)
							.setParameter(3, CommonConstants.DICTTYPE.BUTTON_STATUS_1.label()).getResultList();
					if (dataList != null && dataList.size() > 0) {
						HbeaconWarning warning = (HbeaconWarning) dataList.get(0);
						warning.setCancelTime(cancelTime);
						warning.setLastUpdateDateTime(CommonUtil.getCurrTimes());
						warning.setFlag(commonService.getDicttype(CommonConstants.DICTTYPE.BUTTON_STATUS_2.label()));
						dslJpaService.setEntityClass(HbeaconWarning.class);
						dslJpaService.update(warning);
						List<User> users = userService.getAllUserList(bed.getTenant());// 本机构所有人
						if (users != null && users.size() > 0) {
							// 建立 Message提醒
							Short detailType = (short) ICommonConstants.REMINDDETAILTYPE.HBEACONCALL.ordinal(); // 提醒详细类型
							Message message = new Message();
							message.setType(
									new Integer(CommonConstants.MESSAGE.MESSAGETYPE_NOTICE.label()).shortValue());
							message.setCode(CommonConstants.MESSAGE.MESSAGECODE_CALLINGNOTICE.label());
							message.setCreateTime(CommonUtil.getCurrTimes());
							message.setType((short) ICommonConstants.MESSAGETYPE.REMIND.ordinal());
							message.setDetailType(detailType);
							message.setTenant(bed.getTenant());
							// 设置content debugTest
							Map<String, String> msgMap = new HashMap<String, String>();
							// message.setToUser(user);
							// 设置消息内容
							msgMap.put("createTime", callingTime.toString());
							if (customer != null) {
								msgMap.put("customerId", customer.getId().toString());
								msgMap.put("customerName", customer.getName());
							}
							msgMap.put("bedId", bed.getId().toString());
							msgMap.put("content", "取消按键呼叫");
							message.setContent(CommonUtil.mapToJsonString(msgMap));
							// 使用类型作为通知的业务类型
							message.setBusiness("cancelButtonCalling");
							message.setHasRead(new Integer(0).shortValue());
							// 取得需要发送的用户--发送给所有本机构的人员
							message.setUserList(users);
							dslJpaService.setEntityClass(Message.class);
							message = (Message) dslJpaService.create(message);
							ActionContextHolder.getMessageQueue().addWarningMsg(message);
						}
					}
				}
			} // bed!=null
		} // for
		if(deviceIds.size()>0){	// 修改设备状态为可用状态
			StringBuilder query = new StringBuilder(
					" update Device u set u.deviceStatus = ?1 , u.lastUpdateDateTime = ?2  where  u.id in (:ids) ");
			this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(2, CommonUtil.getCurrTimes())
					.setParameter("ids", deviceIds)
					.executeUpdate();
		}
	}
}
